/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include <向量.h>

#define DEF_2Fs std::vector<vec2>
#define DEF_3Fs std::vector<vec3>
#define DEF_Is std::vector<uint32>


void f_graph_计算直线坐标(vec3 方向, float32 长度, uint32 细分, S_Vec3Array* data);

//从 x:1 y:0.5 开始
Inline void f_graph_计算圆坐标XY(const vec2 中心, const float32 半径, uint32 细分, vec2* 结果, float32 角度 = 360.0f) {
	float32 度数 = (角度 / 细分);
	for (uint32 i = 0; i < 细分; ++i) {
		结果[i].x = 中心.x + cos(M_角度转弧度((float32)i * 度数)) * 半径;
		结果[i].y = 中心.y + sin(M_角度转弧度((float32)i * 度数)) * 半径;
	}
}

Inline void f_graph_计算圆坐标XZ(const vec2 中心, const float32 半径, uint32 细分, vec2* 结果, float32 角度 = 360.0f) {
	float32 度数 = (角度 / 细分);
	for (uint32 i = 0; i < 细分; ++i) {
		结果[i].x = 中心.x + cos(M_角度转弧度((float32)i * 度数)) * 半径;
		结果[i].y = 中心.y + sin(M_角度转弧度((float32)i * 度数)) * 半径;
	}
}

__forceinline void f_计算圆坐标2(const vec2 中心, const float32 半径, uint32 细分, vec2* 结果, float32 角度 = 360.0f) {
	float32 度数 = (角度 / 细分);
	for (uint32 i = 0; i < 细分; ++i) {
		结果[i].x = 中心.x + sin(M_角度转弧度((float32)i * 度数)) * 半径;
		结果[i].y = 中心.y + cos(M_角度转弧度((float32)i * 度数)) * 半径;
	}
}

__forceinline void f_graph_计算圆坐标3(const float32 中心[3], const float32 半径, uint32 细分, float32* 结果) {
	float32 度数 = (360.0 / 细分);
	for (uint32 i = 0; i < 细分; ++i) {
		结果[i*3] = 中心[0] + cos(M_角度转弧度((float32)i * 度数)) * 半径;
		结果[i*3 + 1] = 中心[1] + 0.0;
		结果[i*3 + 2] = 中心[2] + sin(M_角度转弧度((float32)i * 度数)) * 半径;
	}
}
Inline void f_graph_计算圆坐标v3(const vec3 中心, const float32 半径, uint32 细分, vec3* 结果) {
	float32 度数 = (360.0 / 细分);
	for (uint32 i = 0; i < 细分; ++i) {
		结果[i].x = 中心.x + cos(M_角度转弧度((float32)i * 度数)) * 半径;
		结果[i].y = 中心.y + 0.0;
		结果[i].z = 中心.z + sin(M_角度转弧度((float32)i * 度数)) * 半径;
	}
}
void f_graph_计算圆坐标v3_JIT(const vec3 中心, const float32 半径, uint32 细分, S_Vec3Array* data);

void f_计算圆坐标3(const vec3 中心, const float32 半径, uint32 细分, vec3* 结果, E_轴向 轴向);

void f_graph_构建平面坐标(vec3 大小, uvec3 细分, S_Vec3Array* data);



__forceinline void f_构建圆柱_v3(const float32 width, const float32 半径, uint32 段数, vec3* 结果, const bool 是否封盖 = false) {
#pragma loop(vector_on)
	for (uint32 i = 0; i < 段数; i++) {
		const float32 cosTheta = cos(i*M_PI*2.0f / 16.0f);
		const float32 sinTheta = sin(i*M_PI*2.0f / 16.0f);
		const float32 y = 半径*cosTheta;
		const float32 z = 半径*sinTheta;
		结果[2 * i + 0] = vec3{ -width / 2.0f, y, z };
		结果[2 * i + 1] = vec3{ +width / 2.0f, y, z };
	}

}


__forceinline void f_构建圆柱(const float32 width, const vec2 半径, uint32 段数, vec3* 结果, const bool 是否封盖 = false) {
	float32 角度 = M_角度转弧度(360.0 / 段数);
	for (uint32 i = 0; i < 段数; i++) {
		const float32 cosTheta = cos(i * 角度);
		const float32 sinTheta = sin(i * 角度);
		const float32 y1 = 半径.x * cosTheta;
		const float32 z1 = 半径.x * sinTheta;

		const float32 y2 = 半径.x * cosTheta;
		const float32 z2 = 半径.x * sinTheta;

		结果[i] = vec3{ -width / 2.0f, y1, z1 };
		结果[段数 + i] = vec3{ +width / 2.0f, y2, z2 };
	}
}





__forceinline vec2 f_计算点旋转(const vec2& 中心, const float32 半径, float32 弧度) {
	return {
		中心.x + sin(弧度) * 半径,
		中心.y + cos(弧度) * 半径
	};
}




//inline float32 f_平方(float32 x) { return x * x; }


__forceinline void f_计算圆坐标_3dim(const vec3& 中心, float32 半径, uint32 细分, vec3* 结果) {
	float32 度数 = (360.0 / 细分);
	for (uint32 i = 0; i < 细分; ++i) {
		结果[i].x = 中心.x + cos(float32(M_角度转弧度((float32)i * 度数))) * 半径;
		结果[i].y = 中心.y + 0.0;
		结果[i].z = 中心.z + sin(float32(M_角度转弧度((float32)i * 度数))) * 半径;
	}
}



uvec2 f_graph_构建球体(uint32 经度细分, uint32 维度细分, float32 半径, DEF_3Fs& v, DEF_3Fs& n, DEF_2Fs& uv, DEF_Is& i, bool is三角 = true);
void f_graph_构建立方体(vec3 size, uvec3 细分, DEF_3Fs& v, DEF_3Fs& n, DEF_2Fs& uv, DEF_Is& i, bool is三角 = true);
void f_graph_构建立方体线框(vec3 size, uvec3 细分, DEF_3Fs& V, DEF_Is& I, bool is三角 = true);
void f_graph_构建骨骼锥体(vec2 size, DEF_3Fs& V, DEF_3Fs& N, DEF_Is& I, bool is三角 = true);


void f_graph_构建平面(vec2 size, uvec2 细分, DEF_3Fs& v, DEF_3Fs& n, DEF_2Fs& uv, DEF_Is& i, bool is三角 = true);
void f_graph_构建交叉轴(DEF_3Fs& v, DEF_3Fs& n, DEF_2Fs& uv, DEF_Is& i);
void f_graph_构建方向轴(DEF_3Fs& v, DEF_3Fs& n, DEF_2Fs& uv, DEF_Is& i);
void f_graph_构建线框球(DEF_3Fs& v, DEF_3Fs& n, DEF_2Fs& uv, DEF_Is& i, uint32 细分);

//void f_graph_添加间接绘制(std::vector<S_VkDrawIndirectCommand>& indirects, DEF_3Fs& v, DEF_Is& index);

void f_graph_从面采样坐标(std::vector<S_VN>& rvn, const std::vector<S_VN>& vn, const std::vector<uvec3>& i, float32 间隔);


uint32 f_graph_立方体线段(std::vector<S_VC>& 顶点, const vec3& size, const vec3& offset, const S_RGBA8UI& color);
uvec2  f_graph_立方体(std::vector<S_VC>& 顶点, std::vector<uint32>& 索引, const vec3& size, const vec3& offset, const S_RGBA8UI& color);
uvec2  f_graph_圆(std::vector<S_VC>& 顶点, std::vector<uint32>& 索引, const float32 size, const vec3& offset, const S_RGBA8UI& color, E_轴向 轴向 = E_轴向::e_Z);
uvec2  f_graph_锥形(std::vector<S_VC>& 顶点, std::vector<uint32>& 索引, const vec3& 半径高度细分, const vec3& offset, const S_RGBA8UI& color, E_轴向 轴向 = E_轴向::e_Y, bool 面 = false);





